#!/usr/bin/env python
#
'''
Created on 2009-4-11

@author: Wang_Yuan
'''

import os
import os.path
import urllib
import socket
import threading

import wx
import wx.media as media

import settings

class SoundFrame(wx.Frame):
    
    __instance = None
    
    def __init__(self, parent):
        wx.Frame.__init__(self, parent)
        self.mc = media.MediaCtrl(self, style=wx.SIMPLE_BORDER)
        
        self.mc.Bind(media.EVT_MEDIA_LOADED, self.OnMediaLoaded)
        
        self.playnow = False
        self.ready = False
        
        self.threadDict = {}
#        
#        sizer = wx.BoxSizer()
#        sizer.Add(self.mc, proportion=1, flag=wx.EXPAND)
#        sizer.Fit(self)
#        self.SetSizer(sizer)

    @classmethod
    def getInstance(cls):
        if cls.__instance is None:
            cls.__instance = SoundFrame(None)
            cls.__instance.Show(False)
        return cls.__instance
    
    @classmethod
    def hasInstance(cls):
        return cls.__instance is not None
        
    def loadSound(self, fileName):
        def load():
            print 'load:', self.mc.Load(fileName)
        wx.CallAfter(load)
        
    def playSound(self):
        def play():
            if self.ready:
                print 'load:', self.mc.Play()
        wx.CallAfter(play)
        
    def loadAndPlaySound(self, fileName):
        self.playnow = True
        self.loadSound(fileName)
        
    def OnMediaLoaded(self, evt):
        print 'ready! play now:', self.playnow
        self.ready = True
        if self.playnow:
            self.playSound()
            self.playnow = False
    
    def loadWord(self, word, playAfterLoad=False, timeout=5):
        currentThread = threading.currentThread()
        storedThread = self.threadDict.get(word)
        if storedThread is not None and storedThread != currentThread:
            return
                
        CACHE_PATH = settings.getCachePath()
        print CACHE_PATH
        EXT = settings.getExt()
        
        frame = SoundFrame.getInstance()
        frame.ready = False
        
        if not os.path.exists(CACHE_PATH):
            os.mkdir(CACHE_PATH)
        fileName = CACHE_PATH + os.sep + word.replace(' ', '_') + EXT
        print fileName
        if not os.path.exists(fileName) or os.path.getsize(fileName) == 0:
            socket.setdefaulttimeout(timeout)
            try:
                url = urllib.quote(settings.getURL().replace(':word:', word), safe=':/')
                f = urllib.urlopen(url)
                print 'return code: ', f.getcode()
                if f.getcode() == 200:
                    localFile = file(fileName, 'wb')
                    localFile.write(f.read())
                    localFile.close()
                    f.close()
            except Exception, e:
                print e
        if os.path.exists(fileName):
            if playAfterLoad:
                frame.loadAndPlaySound(fileName)
            else:
                frame.loadSound(fileName)
        
                
    def asyncLoadWord(self, word, timeout):
        def target():
            print 'thread start'
            self.loadWord(word, False, timeout=timeout)
            del self.threadDict[word]
        
        t = threading.Thread(target=target, name=word)
        self.threadDict[word] = t
        t.start()
        
                
def playWord():
    def play():
        frame = SoundFrame.getInstance()
        frame.playSound()
            
    if settings.isSoundEnable():
        wx.CallAfter(play)

def loadAndPlayWord(word, timeout=5):
    frame = SoundFrame.getInstance()
    frame.loadWord(word, True, timeout)
            
def asyncLoadWord(word, timeout=None):
    frame = SoundFrame.getInstance()
    frame.asyncLoadWord(word, timeout)

def terminate():
    if SoundFrame.hasInstance():
        frame = SoundFrame.getInstance()
        frame.Destroy()
